<template>
  <div class="p-4">
    <h2 class="text-2xl font-bold mb-4 text-gray-800 dark:text-gray-200">正则表达式测试器</h2>

    <!-- 正则表达式输入 -->
    <div class="mb-6">
      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
        正则表达式
      </label>
      <div class="flex gap-2">
        <div class="flex-1">
          <div class="relative">
            <span class="absolute left-4 top-3 text-gray-400">/</span>
            <input
              v-model="pattern"
              type="text"
              placeholder="输入正则表达式..."
              class="w-full pl-8 pr-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
              @input="testRegex"
            >
            <span class="absolute right-4 top-3 text-gray-400">/</span>
          </div>
        </div>
        <input
          v-model="flags"
          type="text"
          placeholder="flags"
          class="w-20 px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
          @input="testRegex"
        >
      </div>
      <div class="mt-2 text-sm text-gray-500 dark:text-gray-400">
        常用标志：g (全局), i (忽略大小写), m (多行), s (点号匹配所有), u (Unicode)
      </div>
    </div>

    <!-- 测试文本输入 -->
    <div class="mb-6">
      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
        测试文本
      </label>
      <textarea
        v-model="testText"
        placeholder="输入要测试的文本..."
        class="w-full h-40 p-4 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
        @input="testRegex"
      ></textarea>
    </div>

    <!-- 匹配结果 -->
    <div v-if="showResults" class="space-y-6">
      <!-- 匹配统计 -->
      <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
          <div class="text-sm text-gray-500 dark:text-gray-400">匹配总数</div>
          <div class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ matchStats.total }}</div>
        </div>
        <div class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
          <div class="text-sm text-gray-500 dark:text-gray-400">捕获组数</div>
          <div class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ matchStats.groups }}</div>
        </div>
        <div class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
          <div class="text-sm text-gray-500 dark:text-gray-400">执行时间</div>
          <div class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ matchStats.time }}ms</div>
        </div>
      </div>

      <!-- 匹配详情 -->
      <div class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
        <h3 class="text-lg font-semibold mb-4 text-gray-800 dark:text-gray-200">匹配详情</h3>
        
        <!-- 高亮显示 -->
        <div class="mb-4 p-4 bg-gray-50 dark:bg-gray-900 rounded font-mono text-sm whitespace-pre-wrap">
          <span
            v-for="(part, index) in highlightedText"
            :key="index"
            :class="{
              'bg-yellow-200 dark:bg-yellow-900/50': part.isMatch,
              'text-gray-900 dark:text-gray-100': !part.isMatch
            }"
          >{{ part.text }}</span>
        </div>

        <!-- 匹配列表 -->
        <div v-if="matches.length > 0" class="space-y-2">
          <div
            v-for="(match, index) in matches"
            :key="index"
            class="p-3 bg-gray-50 dark:bg-gray-900 rounded"
          >
            <div class="flex justify-between items-center mb-2">
              <span class="text-sm font-medium text-gray-700 dark:text-gray-300">匹配 #{{ index + 1 }}</span>
              <span class="text-sm text-gray-500">位置: {{ match.index }}</span>
            </div>
            <div class="font-mono text-sm">
              <div class="mb-1">
                <span class="text-blue-500">完整匹配:</span>
                <span class="ml-2 text-gray-900 dark:text-gray-100">{{ match.value }}</span>
              </div>
              <template v-if="match.groups.length > 0">
                <div v-for="(group, groupIndex) in match.groups" :key="groupIndex" class="ml-4">
                  <span class="text-green-500">组 {{ groupIndex + 1 }}:</span>
                  <span class="ml-2 text-gray-900 dark:text-gray-100">{{ group }}</span>
                </div>
              </template>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 错误提示 -->
    <div
      v-if="error"
      class="mt-4 p-4 bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg"
    >
      {{ error }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

const pattern = ref('')
const flags = ref('')
const testText = ref('')
const error = ref('')

interface Match {
  value: string
  index: number
  groups: string[]
}

interface MatchStats {
  total: number
  groups: number
  time: number
}

interface TextPart {
  text: string
  isMatch: boolean
}

const matches = ref<Match[]>([])
const matchStats = ref<MatchStats>({
  total: 0,
  groups: 0,
  time: 0
})

const showResults = computed(() => pattern.value && testText.value && !error.value)

const highlightedText = ref<TextPart[]>([])

const testRegex = () => {
  error.value = ''
  matches.value = []
  highlightedText.value = []
  
  if (!pattern.value || !testText.value) return

  try {
    const startTime = performance.now()
    const regex = new RegExp(pattern.value, flags.value)
    
    // 收集所有匹配
    const allMatches: Match[] = []
    let match
    
    if (flags.value.includes('g')) {
      while ((match = regex.exec(testText.value)) !== null) {
        allMatches.push({
          value: match[0],
          index: match.index,
          groups: match.slice(1)
        })
      }
    } else {
      match = regex.exec(testText.value)
      if (match) {
        allMatches.push({
          value: match[0],
          index: match.index,
          groups: match.slice(1)
        })
      }
    }

    matches.value = allMatches
    
    // 更新统计信息
    matchStats.value = {
      total: allMatches.length,
      groups: allMatches[0]?.groups.length || 0,
      time: Math.round((performance.now() - startTime) * 100) / 100
    }

    // 生成高亮文本
    const parts: TextPart[] = []
    let lastIndex = 0
    
    allMatches.forEach(match => {
      if (match.index > lastIndex) {
        parts.push({
          text: testText.value.slice(lastIndex, match.index),
          isMatch: false
        })
      }
      parts.push({
        text: match.value,
        isMatch: true
      })
      lastIndex = match.index + match.value.length
    })

    if (lastIndex < testText.value.length) {
      parts.push({
        text: testText.value.slice(lastIndex),
        isMatch: false
      })
    }

    highlightedText.value = parts

  } catch (e) {
    error.value = e instanceof Error ? e.message : '无效的正则表达式'
  }
}
</script> 